using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using DocumentCreationSystem.Models;

namespace DocumentCreationSystem.Services
{
    /// <summary>
    /// 论文写作服务实现
    /// </summary>
    public class PaperWritingService : IPaperWritingService
    {
        private readonly ILogger<PaperWritingService> _logger;
        private readonly IAIService _aiService;
        private readonly IFileFormatService _fileFormatService;

        public PaperWritingService(
            ILogger<PaperWritingService> logger,
            IAIService aiService,
            IFileFormatService fileFormatService)
        {
            _logger = logger;
            _aiService = aiService;
            _fileFormatService = fileFormatService;
        }

        /// <summary>
        /// 分析素材文件
        /// </summary>
        public async Task<MaterialAnalysisResult> AnalyzeMaterialsAsync(
            List<string> materialFiles, 
            CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogInformation($"开始分析 {materialFiles.Count} 个素材文件");

                var result = new MaterialAnalysisResult();
                var allContent = new StringBuilder();

                // 读取所有素材文件内容
                foreach (var filePath in materialFiles)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    if (!File.Exists(filePath))
                    {
                        _logger.LogWarning($"素材文件不存在: {filePath}");
                        continue;
                    }

                    try
                    {
                        var content = await _fileFormatService.ReadContentAsync(filePath);
                        allContent.AppendLine($"=== {Path.GetFileName(filePath)} ===");
                        allContent.AppendLine(content);
                        allContent.AppendLine();
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, $"读取素材文件失败: {filePath}");
                    }
                }

                var materialContent = allContent.ToString();
                if (string.IsNullOrWhiteSpace(materialContent))
                {
                    throw new InvalidOperationException("无法读取任何素材内容");
                }

                // 使用AI分析素材
                var analysisPrompt = BuildMaterialAnalysisPrompt(materialContent);
                var analysisResponse = await _aiService.GenerateTextAsync(analysisPrompt, 3000, 0.6f);

                // 解析AI分析结果
                result = ParseMaterialAnalysis(analysisResponse);
                result.Summary = await GenerateMaterialSummary(materialContent);

                _logger.LogInformation($"素材分析完成，识别到 {result.MainTopics.Count} 个主要主题");
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "分析素材文件时发生错误");
                throw;
            }
        }

        /// <summary>
        /// 生成论文大纲
        /// </summary>
        public async Task<PaperOutline> GenerateOutlineAsync(
            PaperGenerationRequest request, 
            MaterialAnalysisResult materialAnalysis,
            CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogInformation("开始生成论文大纲");

                var outlinePrompt = BuildOutlineGenerationPrompt(request, materialAnalysis);
                var outlineResponse = await _aiService.GenerateTextAsync(outlinePrompt, 2500, 0.7f);

                var outline = ParsePaperOutline(outlineResponse, request);
                
                // 分配字数
                AllocateWordCounts(outline, request.TargetWordCount);

                _logger.LogInformation($"论文大纲生成完成，包含 {outline.SectionOutlines.Count} 个章节");
                return outline;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "生成论文大纲时发生错误");
                throw;
            }
        }

        /// <summary>
        /// 生成论文标题
        /// </summary>
        public async Task<string> GenerateTitleAsync(
            PaperGenerationRequest request, 
            MaterialAnalysisResult materialAnalysis,
            CancellationToken cancellationToken = default)
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(request.Title))
                {
                    return request.Title;
                }

                _logger.LogInformation("开始生成论文标题");

                var titlePrompt = BuildTitleGenerationPrompt(request, materialAnalysis);
                var titleResponse = await _aiService.GenerateTextAsync(titlePrompt, 200, 0.8f);

                var title = titleResponse.Trim().Trim('"', '\'', '《', '》');
                
                _logger.LogInformation($"论文标题生成完成: {title}");
                return title;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "生成论文标题时发生错误");
                throw;
            }
        }

        /// <summary>
        /// 生成论文章节内容
        /// </summary>
        public async Task<PaperSection> GenerateSectionAsync(
            SectionOutline sectionOutline,
            PaperGenerationRequest request,
            MaterialAnalysisResult materialAnalysis,
            List<PaperSection> previousSections,
            CancellationToken cancellationToken = default)
        {
            try
            {
                _logger.LogInformation($"开始生成章节: {sectionOutline.Title}");

                var sectionPrompt = BuildSectionGenerationPrompt(
                    sectionOutline, request, materialAnalysis, previousSections);

                var maxTokens = Math.Max(sectionOutline.EstimatedWordCount * 2, 1000);
                var sectionContent = await _aiService.GenerateTextAsync(sectionPrompt, maxTokens, 0.7f);

                var section = new PaperSection
                {
                    Title = sectionOutline.Title,
                    Content = sectionContent.Trim(),
                    SectionType = sectionOutline.SectionType,
                    Order = sectionOutline.Order,
                    WordCount = CountWords(sectionContent)
                };

                _logger.LogInformation($"章节生成完成: {section.Title}, 字数: {section.WordCount}");
                return section;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"生成章节内容时发生错误: {sectionOutline.Title}");
                throw;
            }
        }

        /// <summary>
        /// 生成完整论文
        /// </summary>
        public async Task<PaperGenerationResult> GeneratePaperAsync(
            PaperGenerationRequest request,
            IProgress<string>? progress = null,
            CancellationToken cancellationToken = default)
        {
            var stopwatch = Stopwatch.StartNew();
            var result = new PaperGenerationResult();

            try
            {
                _logger.LogInformation("开始生成完整论文");

                // 1. 分析素材
                progress?.Report("正在分析素材文件...");
                var materialAnalysis = await AnalyzeMaterialsAsync(request.MaterialFiles, cancellationToken);

                // 2. 生成标题
                progress?.Report("正在生成论文标题...");
                var title = await GenerateTitleAsync(request, materialAnalysis, cancellationToken);
                result.Title = title;

                // 3. 生成大纲
                progress?.Report("正在生成论文大纲...");
                var outline = await GenerateOutlineAsync(request, materialAnalysis, cancellationToken);

                // 4. 生成各章节内容
                var sections = new List<PaperSection>();
                
                for (int i = 0; i < outline.SectionOutlines.Count; i++)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var sectionOutline = outline.SectionOutlines[i];
                    progress?.Report($"正在生成章节: {sectionOutline.Title} ({i + 1}/{outline.SectionOutlines.Count})");

                    var section = await GenerateSectionAsync(
                        sectionOutline, request, materialAnalysis, sections, cancellationToken);
                    
                    sections.Add(section);
                }

                // 5. 格式化论文内容
                progress?.Report("正在格式化论文内容...");
                var formattedContent = FormatPaperContent(sections, request, title);

                // 6. 设置结果
                result.IsSuccess = true;
                result.Content = formattedContent;
                result.Sections = sections;
                result.Statistics = new PaperGenerationStatistics
                {
                    TotalWordCount = CountWords(formattedContent),
                    GenerationTime = stopwatch.Elapsed,
                    MaterialFilesCount = request.MaterialFiles.Count,
                    SectionsCount = sections.Count,
                    MaterialUtilizationRate = CalculateMaterialUtilization(materialAnalysis, sections)
                };

                _logger.LogInformation($"论文生成完成，总字数: {result.Statistics.TotalWordCount}, 耗时: {stopwatch.Elapsed}");
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "生成完整论文时发生错误");
                result.IsSuccess = false;
                result.ErrorMessage = ex.Message;
                return result;
            }
            finally
            {
                stopwatch.Stop();
            }
        }

        /// <summary>
        /// 格式化论文内容
        /// </summary>
        public string FormatPaperContent(List<PaperSection> sections, PaperGenerationRequest request, string title)
        {
            var content = new StringBuilder();

            // 添加标题
            content.AppendLine(title);
            content.AppendLine(new string('=', title.Length));
            content.AppendLine();

            // 添加各章节内容
            foreach (var section in sections.OrderBy(s => s.Order))
            {
                content.AppendLine($"## {section.Title}");
                content.AppendLine();
                content.AppendLine(section.Content);
                content.AppendLine();
                content.AppendLine();
            }

            return content.ToString();
        }

        /// <summary>
        /// 验证论文质量
        /// </summary>
        public async Task<int> ValidatePaperQualityAsync(string content, PaperGenerationRequest request)
        {
            try
            {
                var validationPrompt = BuildQualityValidationPrompt(content, request);
                var validationResponse = await _aiService.GenerateTextAsync(validationPrompt, 500, 0.5f);

                // 从AI响应中提取质量评分
                var score = ExtractQualityScore(validationResponse);
                return Math.Max(0, Math.Min(100, score));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "验证论文质量时发生错误");
                return 70; // 默认评分
            }
        }

        #region 私有辅助方法

        /// <summary>
        /// 构建素材分析提示词
        /// </summary>
        private string BuildMaterialAnalysisPrompt(string materialContent)
        {
            return $@"请分析以下学术素材内容，提取关键信息：

素材内容：
{materialContent}

请按以下格式分析：
1. 主要主题（列出3-5个核心主题）
2. 关键概念（列出重要的学术概念和术语）
3. 研究方法（如果有，列出提到的研究方法）
4. 重要发现（列出主要的研究发现或结论）
5. 参考文献信息（如果有引用信息）
6. 建议的论文结构（基于素材内容建议合适的论文章节结构）

请用中文回答，每个部分用换行分隔，每个要点用短横线加空格开头。";
        }

        /// <summary>
        /// 解析素材分析结果
        /// </summary>
        private MaterialAnalysisResult ParseMaterialAnalysis(string analysisResponse)
        {
            var result = new MaterialAnalysisResult();
            var lines = analysisResponse.Split('\n', StringSplitOptions.RemoveEmptyEntries);

            string currentSection = "";
            foreach (var line in lines)
            {
                var trimmedLine = line.Trim();

                if (trimmedLine.Contains("主要主题"))
                    currentSection = "topics";
                else if (trimmedLine.Contains("关键概念"))
                    currentSection = "concepts";
                else if (trimmedLine.Contains("研究方法"))
                    currentSection = "methods";
                else if (trimmedLine.Contains("重要发现"))
                    currentSection = "findings";
                else if (trimmedLine.Contains("参考文献"))
                    currentSection = "references";
                else if (trimmedLine.Contains("建议的论文结构"))
                    currentSection = "structure";
                else if (trimmedLine.StartsWith("- ") || trimmedLine.StartsWith("• "))
                {
                    var content = trimmedLine.StartsWith("- ") ? trimmedLine.Substring(2).Trim() :
                                 trimmedLine.StartsWith("• ") ? trimmedLine.Substring(2).Trim() :
                                 trimmedLine.Trim();
                    switch (currentSection)
                    {
                        case "topics":
                            result.MainTopics.Add(content);
                            break;
                        case "concepts":
                            result.KeyConcepts.Add(content);
                            break;
                        case "methods":
                            result.ResearchMethods.Add(content);
                            break;
                        case "findings":
                            result.KeyFindings.Add(content);
                            break;
                        case "references":
                            result.References.Add(content);
                            break;
                        case "structure":
                            result.SuggestedStructure.Add(content);
                            break;
                    }
                }
            }

            return result;
        }

        /// <summary>
        /// 生成素材摘要
        /// </summary>
        private async Task<string> GenerateMaterialSummary(string materialContent)
        {
            var summaryPrompt = $@"请对以下学术素材进行简洁的摘要，控制在200字以内：

{materialContent.Substring(0, Math.Min(materialContent.Length, 3000))}

摘要要求：
1. 概括主要内容和观点
2. 突出核心贡献和发现
3. 语言简洁学术化
4. 用中文表达";

            return await _aiService.GenerateTextAsync(summaryPrompt, 300, 0.6f);
        }

        /// <summary>
        /// 构建大纲生成提示词
        /// </summary>
        private string BuildOutlineGenerationPrompt(PaperGenerationRequest request, MaterialAnalysisResult materialAnalysis)
        {
            var structureInfo = string.Join("\n", request.Structure.GetType().GetProperties()
                .Where(p => p.PropertyType == typeof(bool) && (bool)p.GetValue(request.Structure)!)
                .Select(p => $"- {GetSectionDisplayName(p.Name)}"));

            var topicsInfo = string.Join(", ", materialAnalysis.MainTopics);
            var conceptsInfo = string.Join(", ", materialAnalysis.KeyConcepts);

            var userRequirementsSection = !string.IsNullOrWhiteSpace(request.UserRequirements)
                ? $@"

用户特殊要求：
{request.UserRequirements}"
                : "";

            return $@"请为以下论文生成详细大纲：

论文信息：
- 标题：{request.Title ?? "待生成"}
- 类型：{request.PaperType}
- 领域：{request.Field}
- 目标字数：{request.TargetWordCount}字
- 写作风格：{request.WritingStyle}

素材分析结果：
- 主要主题：{topicsInfo}
- 关键概念：{conceptsInfo}
- 素材摘要：{materialAnalysis.Summary}

需要包含的章节：
{structureInfo}{userRequirementsSection}

请按以下格式生成大纲：
1. 摘要大纲（如果需要）
2. 各章节大纲，每个章节包括：
   - 章节标题
   - 主要内容要点（3-5个要点）
   - 预估字数

要求：
1. 大纲要符合{request.PaperType}的学术规范
2. 章节安排要逻辑清晰、层次分明
3. 充分利用提供的素材内容
4. 符合{request.Field}领域的特点
5. 严格遵循用户的特殊要求（如有）";
        }

        /// <summary>
        /// 获取章节显示名称
        /// </summary>
        private string GetSectionDisplayName(string propertyName)
        {
            return propertyName switch
            {
                "IncludeAbstract" => "摘要",
                "IncludeKeywords" => "关键词",
                "IncludeIntroduction" => "引言",
                "IncludeLiteratureReview" => "文献综述",
                "IncludeMethodology" => "研究方法",
                "IncludeResults" => "结果分析",
                "IncludeDiscussion" => "讨论",
                "IncludeConclusion" => "结论",
                "IncludeReferences" => "参考文献",
                _ => propertyName
            };
        }

        /// <summary>
        /// 解析论文大纲
        /// </summary>
        private PaperOutline ParsePaperOutline(string outlineResponse, PaperGenerationRequest request)
        {
            var outline = new PaperOutline();
            var lines = outlineResponse.Split('\n', StringSplitOptions.RemoveEmptyEntries);

            SectionOutline? currentSection = null;
            int sectionOrder = 1;

            foreach (var line in lines)
            {
                var trimmedLine = line.Trim();

                // 检测章节标题
                if (trimmedLine.StartsWith("##") || trimmedLine.Contains("章节") ||
                    trimmedLine.Contains("摘要") || trimmedLine.Contains("引言") ||
                    trimmedLine.Contains("文献") || trimmedLine.Contains("方法") ||
                    trimmedLine.Contains("结果") || trimmedLine.Contains("讨论") ||
                    trimmedLine.Contains("结论"))
                {
                    if (currentSection != null)
                    {
                        outline.SectionOutlines.Add(currentSection);
                    }

                    currentSection = new SectionOutline
                    {
                        Title = trimmedLine.Replace("##", "").Trim(),
                        Order = sectionOrder++,
                        SectionType = DetermineSectionType(trimmedLine)
                    };
                }
                else if (currentSection != null && trimmedLine.StartsWith("- "))
                {
                    currentSection.KeyPoints.Add(trimmedLine.Substring(2).Trim());
                }
                else if (trimmedLine.Contains("摘要大纲") && trimmedLine.Contains(":"))
                {
                    outline.AbstractOutline = trimmedLine.Split(':', 2)[1].Trim();
                }
            }

            if (currentSection != null)
            {
                outline.SectionOutlines.Add(currentSection);
            }

            return outline;
        }

        /// <summary>
        /// 确定章节类型
        /// </summary>
        private string DetermineSectionType(string title)
        {
            var lowerTitle = title.ToLower();

            if (lowerTitle.Contains("摘要")) return "Abstract";
            if (lowerTitle.Contains("关键词")) return "Keywords";
            if (lowerTitle.Contains("引言") || lowerTitle.Contains("介绍")) return "Introduction";
            if (lowerTitle.Contains("文献") || lowerTitle.Contains("综述")) return "LiteratureReview";
            if (lowerTitle.Contains("方法") || lowerTitle.Contains("methodology")) return "Methodology";
            if (lowerTitle.Contains("结果") || lowerTitle.Contains("分析")) return "Results";
            if (lowerTitle.Contains("讨论")) return "Discussion";
            if (lowerTitle.Contains("结论")) return "Conclusion";
            if (lowerTitle.Contains("参考文献") || lowerTitle.Contains("引用")) return "References";

            return "Content";
        }

        /// <summary>
        /// 分配字数
        /// </summary>
        private void AllocateWordCounts(PaperOutline outline, int targetWordCount)
        {
            var totalSections = outline.SectionOutlines.Count;
            if (totalSections == 0) return;

            // 预定义各章节的字数比例
            var sectionWeights = new Dictionary<string, float>
            {
                ["Abstract"] = 0.05f,
                ["Keywords"] = 0.02f,
                ["Introduction"] = 0.15f,
                ["LiteratureReview"] = 0.20f,
                ["Methodology"] = 0.15f,
                ["Results"] = 0.20f,
                ["Discussion"] = 0.15f,
                ["Conclusion"] = 0.08f,
                ["References"] = 0.0f // 参考文献不计入正文字数
            };

            var totalWeight = outline.SectionOutlines
                .Sum(s => sectionWeights.GetValueOrDefault(s.SectionType, 0.1f));

            foreach (var section in outline.SectionOutlines)
            {
                var weight = sectionWeights.GetValueOrDefault(section.SectionType, 0.1f);
                section.EstimatedWordCount = (int)(targetWordCount * weight / totalWeight);
                outline.WordCountAllocation[section.Title] = section.EstimatedWordCount;
            }
        }

        /// <summary>
        /// 构建标题生成提示词
        /// </summary>
        private string BuildTitleGenerationPrompt(PaperGenerationRequest request, MaterialAnalysisResult materialAnalysis)
        {
            var topicsInfo = string.Join("、", materialAnalysis.MainTopics.Take(3));

            return $@"请为以下论文生成一个学术性的标题：

论文信息：
- 类型：{request.PaperType}
- 领域：{request.Field}
- 写作风格：{request.WritingStyle}

主要研究主题：{topicsInfo}

关键概念：{string.Join("、", materialAnalysis.KeyConcepts.Take(5))}

要求：
1. 标题要准确反映论文的核心内容
2. 符合{request.Field}领域的学术规范
3. 简洁明了，一般不超过20个字
4. 体现{request.PaperType}的特点
5. 只返回标题，不要其他解释

请生成3个候选标题，选择最佳的一个返回。";
        }

        /// <summary>
        /// 构建章节生成提示词
        /// </summary>
        private string BuildSectionGenerationPrompt(
            SectionOutline sectionOutline,
            PaperGenerationRequest request,
            MaterialAnalysisResult materialAnalysis,
            List<PaperSection> previousSections)
        {
            var keyPointsInfo = string.Join("\n", sectionOutline.KeyPoints.Select(p => $"- {p}"));
            var previousContent = previousSections.Count > 0
                ? string.Join("\n\n", previousSections.TakeLast(2).Select(s => $"{s.Title}:\n{s.Content.Substring(0, Math.Min(s.Content.Length, 300))}..."))
                : "无";

            var userRequirementsSection = !string.IsNullOrWhiteSpace(request.UserRequirements)
                ? $@"

用户特殊要求：
{request.UserRequirements}"
                : "";

            return $@"请为论文生成以下章节的内容：

章节信息：
- 标题：{sectionOutline.Title}
- 类型：{sectionOutline.SectionType}
- 目标字数：约{sectionOutline.EstimatedWordCount}字

章节要点：
{keyPointsInfo}

论文背景：
- 类型：{request.PaperType}
- 领域：{request.Field}
- 写作风格：{request.WritingStyle}
- 引用风格：{request.CitationStyle}

相关素材信息：
- 主要主题：{string.Join("、", materialAnalysis.MainTopics)}
- 关键概念：{string.Join("、", materialAnalysis.KeyConcepts)}
- 重要发现：{string.Join("、", materialAnalysis.KeyFindings)}

前面章节内容（供参考）：
{previousContent}{userRequirementsSection}

要求：
1. 内容要符合{request.PaperType}的学术规范
2. 语言风格要{request.WritingStyle}
3. 逻辑清晰，论证充分
4. 与前面章节保持连贯性
5. 充分利用提供的素材信息
6. 字数控制在{sectionOutline.EstimatedWordCount}字左右
7. 如需引用，请使用{request.CitationStyle}格式
8. 严格遵循用户的特殊要求（如有）

请直接生成章节内容，不要包含章节标题。";
        }

        /// <summary>
        /// 构建质量验证提示词
        /// </summary>
        private string BuildQualityValidationPrompt(string content, PaperGenerationRequest request)
        {
            return $@"请评估以下论文的质量，给出0-100分的评分：

论文类型：{request.PaperType}
学科领域：{request.Field}
目标字数：{request.TargetWordCount}

论文内容：
{content.Substring(0, Math.Min(content.Length, 2000))}...

评估标准：
1. 学术规范性（格式、引用等）
2. 内容完整性（结构完整、逻辑清晰）
3. 论证充分性（论据充分、推理合理）
4. 语言表达（准确、流畅、学术化）
5. 创新性（观点新颖、有价值）

请只返回一个0-100之间的数字评分。";
        }

        /// <summary>
        /// 提取质量评分
        /// </summary>
        private int ExtractQualityScore(string validationResponse)
        {
            var response = validationResponse.Trim();

            // 尝试提取数字
            var numbers = System.Text.RegularExpressions.Regex.Matches(response, @"\d+");

            foreach (System.Text.RegularExpressions.Match match in numbers)
            {
                if (int.TryParse(match.Value, out int score) && score >= 0 && score <= 100)
                {
                    return score;
                }
            }

            return 75; // 默认评分
        }

        /// <summary>
        /// 计算字数
        /// </summary>
        private int CountWords(string text)
        {
            if (string.IsNullOrWhiteSpace(text))
                return 0;

            // 对于中文文本，按字符数计算
            return text.Replace(" ", "").Replace("\n", "").Replace("\r", "").Length;
        }

        /// <summary>
        /// 计算素材利用率
        /// </summary>
        private float CalculateMaterialUtilization(MaterialAnalysisResult materialAnalysis, List<PaperSection> sections)
        {
            try
            {
                var totalConcepts = materialAnalysis.MainTopics.Count + materialAnalysis.KeyConcepts.Count;
                if (totalConcepts == 0) return 0.5f;

                var usedConcepts = 0;
                var allSectionContent = string.Join(" ", sections.Select(s => s.Content)).ToLower();

                foreach (var topic in materialAnalysis.MainTopics)
                {
                    if (allSectionContent.Contains(topic.ToLower()))
                        usedConcepts++;
                }

                foreach (var concept in materialAnalysis.KeyConcepts)
                {
                    if (allSectionContent.Contains(concept.ToLower()))
                        usedConcepts++;
                }

                return Math.Min(1.0f, (float)usedConcepts / totalConcepts);
            }
            catch
            {
                return 0.5f; // 默认利用率
            }
        }

        #endregion
    }
}
